import { cursors, drawEvents, modes, passingMode } from "../constants";
import doubleClickZoom from "../lib/double_click_zoom";
import * as Constants from "../constants";

const PassingMode = (originalMode, type) => {
  const {
    onSetup: originOnSetup,
    onTap: originTap,
    onTouchMove: originOnTouchMove,
    ...restOriginMethods
  } = originalMode;
  const newmode = {
    originOnSetup,
    originOnTouchMove,
    originTap,
    ...restOriginMethods,
  };

  newmode.onSetup = function ({callBack, errorBack}) {
    const state = this.originOnSetup();

    if ("point" in state) state.feature_type = "point";
    else if ("line" in state) state.feature_type = "line";
    else if ("currentLine" in state) state.feature_type = "paint-line";
    else state.feature_type = "polygon";

    state.callBack = callBack;
    state.errorBack = errorBack;

    return state;
  };

  newmode.onTap = newmode.onClick = function (state, e) {
    try {
      if (state.feature_type === "point") {
        state.point.updateCoordinate("", e.lngLat.lng, e.lngLat.lat);

        if (typeof state.callBack === "function") state.callBack(state.point.toGeoJSON(), e.point);
        else
          this.map.fire("draw.passing-create", {
            features: [state.point.toGeoJSON()],
          });

        this.changeMode(modes.SIMPLE_SELECT, {}, { silent: true });
      } else this.originTap(state, e);
    } catch (err) {
      if (state.errorBack) if (typeof state.errorBack === "function") state.errorBack(err);
      this.changeMode(modes.SIMPLE_SELECT, {}, { silent: true });
    }
  };

  newmode.onTouchMove = function (state, e) {
    if (state.feature_type !== "point") {
      this.originOnTouchMove(state, e);
    }
  };

  newmode.onStop = function (state) {
    if ("point" in state) {
      this.deleteFeature([state.point.id], { silent: true });
    } else {
      let f = state.line || state.polygon;

      if (state.feature_type === "paint-line") {
        if(!state.currentLineFeature) return;
        f = this.newFeature({
          id: state.currentLineFeature.id,
          type: Constants.geojsonTypes.FEATURE,
          properties: {},
          geometry: {
            type: Constants.geojsonTypes.LINE_STRING,
            coordinates: state.features[0],
          },
        });
      }
      // check to see if we've deleted this feature
      if (this.getFeature(f.id) === undefined) return;
      //remove last added coordinate
      if (state.feature_type === "line" || state.feature_type === "paint-line") {
        f.removeCoordinate(`${state.currentVertexPosition}`);
      } else {
        f.removeCoordinate(`0.${state.currentVertexPosition}`);
      }
      if (f.isValid()) {
        if (typeof state.callBack === "function") state.callBack(f.toGeoJSON());
        else {
          this.map.fire(Constants.events.CREATE, { features: [f.toGeoJSON()] });
        }
      }
      this.deleteFeature([f.id], { silent: true });
      this.changeMode(modes.SIMPLE_SELECT, {}, { silent: true });
    }
  };

  return newmode;
};

export default PassingMode;
